home *** CD-ROM | disk | FTP | other *** search
- function PROT_ContentAnalyzer(listWarden, threadQueue, opt_testing) {
- this.listWarden_ = listWarden;
- this.threadQueue_ = threadQueue;
- this.testing_ = !!opt_testing;
- this.debugZone = "contentanalyzer";
- this.docs_ = [];
- this.time_ = PROT_ContentAnalyzer.MIN_TIME;
- this.numNodes_ = PROT_ContentAnalyzer.MIN_NODES;
- this.reportURL = PROT_globalStore.getResultsReportURL();
- this.urlCrypto_ = null;
- this.useCrypto_ = !this.testing_;
- this.prefs_ = new G_Preferences();
- var contentAnalyzerEnabledPrefName =
- PROT_globalStore.getContentAnalyzerEnabledPrefName();
- var contentAnalyzerPrefObserver = BindToObject(this.onPrefChanged,
- this);
- this.prefs_.addObserver(contentAnalyzerEnabledPrefName,
- contentAnalyzerPrefObserver);
- this.isEnabled_ = false;
- this.onPrefChanged(contentAnalyzerEnabledPrefName);
- G_Debug(this, "content analyzer initialized");
- }
- PROT_ContentAnalyzer.MAX_DOCS = 3;
- PROT_ContentAnalyzer.MAX_TIME = 60*1000;
- PROT_ContentAnalyzer.MAX_NODES = 500;
- PROT_ContentAnalyzer.prototype.onPrefChanged = function(prefName) {
- this.isEnabled_ = this.prefs_.getPref(prefName, false);
- var compatibleVersion = (new G_ThisFirefoxVersion()).
- compareToString("1.5.0.2");
- if (compatibleVersion < 0)
- this.isEnabled_ = false;
- this.maybeToggleDoWork();
- }
- PROT_ContentAnalyzer.prototype.maybeToggleDoWork = function() {
- if (this.isEnabled_ === true) {
- this.iterator_ = new PROT_SafeDOMIterator(this.listWarden_,
- this,
- this.threadQueue_);
- this.alarm_ = new G_Alarm(BindToObject(this.doWork, this),
- 1000,
- true /* repeating */);
- } else if (this.isEnabled_ === false) {
- if (this.alarm_)
- this.alarm_.cancel();
- this.alarm_ = null;
- this.iterator_ = null;
- }
- }
- PROT_ContentAnalyzer.prototype.maybeAnalyzeDoc = function(doc) {
- if (!this.isEnabled_ || !doc)
- return;
- if (this.listWarden_.isWhiteURL(doc.URL)) {
- G_Debug(this, "whitelist suppressing analysis");
- return;
- }
- if (this.docs_.length < PROT_ContentAnalyzer.MAX_DOCS) {
- this.docs_.push(doc);
- G_Debug(this, "pushing " + doc.URL.slice(-50));
- this.numDrops_ = 0;
- }
- else {
- G_Debug(this, this.docs_.length + " docs on queue, skipping " + doc.URL.slice(-50));
- this.numDrops_++;
- if (this.numDrops_ >= 2) {
- G_Debug(this, "too many drops, aborting");
- this.iterator_.abort();
- }
- }
- }
- PROT_ContentAnalyzer.prototype.doWork = function() {
- if (!this.isEnabled_)
- return;
- if (this.docs_.length > 0 && this.iterator_.isReady()) {
- this.iterator_.start(this.docs_[0],
- PROT_ContentAnalyzer.MAX_TIME,
- PROT_ContentAnalyzer.MAX_NODES);
- }
- }
- PROT_ContentAnalyzer.prototype.reportResults = function(doc, results) {
- if (!this.urlCrypto_)
- this.urlCrypto_ = new PROT_UrlCrypto();
- var reportURL = this.reportURL;
- var params = {"url": doc.URL, "results": results};
- if (this.useCrypto_) {
- params = this.urlCrypto_.maybeCryptParams(params);
- }
- for (var param in params) {
- reportURL += param + "=" +
- encodeURIComponent(params[param]) + "&";
- }
- G_Debug(this, "reportURL: " + reportURL);
- if (this.prefs_.getPref(PROT_globalStore.getSendUserReportsPrefName(),
- false))
- (new PROT_XMLFetcher(true /* strip cookies */)).get(reportURL, null /* no cb */);
- }
- PROT_ContentAnalyzer.prototype.docIsComplete = function(doc, results) {
- if (!this.testing_ && results != "") {
- this.reportResults(doc, results);
- }
- if (results == "")
- G_Debug(this, "empty results for " + doc.URL.slice(-50));
- else
- G_Debug(this, "sandbox results for " + doc.URL + ": " + results);
- this.docs_.shift();
- }
- function PROT_SafeDOMIterator(listWarden, contentAnalyzer, threadQueue) {
- this.contentAnalyzer_ = contentAnalyzer;
- this.threadQueue_ = threadQueue;
- this.debugZone = "domiterator";
- this.registrar_ = new EventRegistrar(["abort", "reset", "results", "meta"]);
- this.attrs = {};
- this.status_ = PROT_SafeDOMIterator.states.READY;
- this.sandboxMgr_ = new PROT_SandboxManager(this,
- listWarden,
- "goog-sandbox-text");
- }
- PROT_SafeDOMIterator.whatToShow = Ci.nsIDOMNodeFilter.SHOW_ELEMENT |
- Ci.nsIDOMNodeFilter.SHOW_TEXT;
- PROT_SafeDOMIterator.CHUNK_SIZE = 10;
- PROT_SafeDOMIterator.states = { WORKING: "working",
- READY: "ready",
- ABORT: "abort"}
- PROT_SafeDOMIterator.MULTIPLIER = 2.5;
- PROT_SafeDOMIterator.prototype.start = function(doc, maxTime, maxNodes) {
- if (!doc || !this.isReady()) {
- G_Debug(this, "is ready: " + this.isReady());
- return;
- }
- this.doc_ = doc;
- this.maxTime_ = maxTime;
- this.maxNodes_ = maxNodes;
- this.fire("reset", {});
- this.fire("meta", { url: doc.URL,
- title: doc.title,
- referrer: doc.referrer,
- callback: BindToObject(this.maybeStartWalk, this) });
- }
- PROT_SafeDOMIterator.prototype.maybeStartWalk = function(shouldWalk) {
- if (!shouldWalk) {
- this.status_ = PROT_SafeDOMIterator.states.READY;
- G_Debug(this, "sandbox not interested, ignoring " + this.doc_.URL.slice(-50));
- this.contentAnalyzer_.docIsComplete(this.doc_, "");
- return;
- }
- this.status_ = PROT_SafeDOMIterator.states.WORKING;
- this.iter_ = this.doc_.createTreeWalker(this.doc_.documentElement,
- PROT_SafeDOMIterator.whatToShow,
- null, /* no NodeFilter */
- true /* expand entities */);
- new G_Alarm(BindToObject(this.abort, this), this.maxTime_);
- this.alarm_ = new G_ConditionalAlarm(BindToObject(this.maybeAbort, this),
- 1*1000 /* period in ms */,
- true /* repeating */);
- this.targetNodes_ =
- PROT_SafeDOMIterator.CHUNK_SIZE*PROT_SafeDOMIterator.MULTIPLIER;
- this.numNodes_ = 0;
- this.threadQueue_.addWorker(BindToObject(this.walkDOM, this),
- BindToObject(this.finishIfComplete, this));
- this.threadQueue_.run();
- }
- PROT_SafeDOMIterator.prototype.maybeAbort = function() {
- if (this.numNodes_ < this.targetNodes_ ||
- !this.iter_.currentNode ||
- this.numNodes_ >= this.maxNodes_) {
- this.abort();
- return true;
- }
- this.targetNodes_ = this.numNodes_ +
- PROT_SafeDOMIterator.CHUNK_SIZE*PROT_SafeDOMIterator.MULTIPLIER;
- G_Debug(this, "current nodes: " + this.numNodes_ + " target nodes: " +
- this.targetNodes_);
- return false;
- }
- PROT_SafeDOMIterator.prototype.extractFeatures = function(n) {
- if (!(this.attrs.hasOwnProperty(n.nodeName)))
- return;
- var attrs = this.attrs[n.nodeName];
- var values = {};
- var MAX_LEN = 1024; // Never pass more than 1K to the sandbox
- values.nodeName = n.nodeName;
- for (var i = 0; i < attrs.length; i++) {
- if (attrs[i] == "nodeValue" && n.nodeName == "#text") {
- values[attrs[i]] = n[attrs[i]].toString().substring(0, MAX_LEN);
- } else if (n.getAttribute(attrs[i])) {
- values[attrs[i]] = n.getAttribute(attrs[i]).substring(0, MAX_LEN);
- } else {
- values[attrs[i]] = "undefined";
- }
- }
- return values;
- }
- PROT_SafeDOMIterator.prototype.union = function(attrs1, attrs2) {
- var newattrs = attrs1.concat(attrs2);
- newattrs = newattrs.sort();
- for (var i = newattrs.length-1; i >= 1; i--) {
- if (newattrs[i] == newattrs[i-1] || !newattrs[i])
- newattrs.splice(i, 1);
- }
- return newattrs;
- }
- PROT_SafeDOMIterator.prototype.registerEvent = function(eventType, attrs) {
- if (!this.registrar_.isKnownEventType(eventType)) {
- this.registrar_.addEventType(eventType);
- }
- if (!this.attrs[eventType])
- this.attrs[eventType] = [];
- this.attrs[eventType] = this.union(this.attrs[eventType], attrs);
- }
- PROT_SafeDOMIterator.prototype.registerHandler = function(nodeName,
- handler,
- attrs) {
- this.registrar_.registerListener(nodeName, handler);
- this.registerEvent(nodeName, attrs);
- }
- PROT_SafeDOMIterator.prototype.removeHandlers = function() {
- this.registrar_ = new EventRegistrar(["abort", "reset", "results", "meta"]);
- }
- PROT_SafeDOMIterator.prototype.fire = function(eventType, e) {
- this.registrar_.fire(eventType, e);
- }
- PROT_SafeDOMIterator.prototype.walkDOM = function() {
- for (var i = 0; i < PROT_SafeDOMIterator.CHUNK_SIZE; i++) {
- var n = this.iter_.nextNode();
- if (!n)
- return;
- if (!(this.attrs.hasOwnProperty(n.nodeName))) {
- continue;
- }
- var event = this.extractFeatures(n);
- event.callback = BindToObject(this.maybeSetAbort, this);
- this.fire(n.nodeName, event);
- }
- this.numNodes_ += PROT_SafeDOMIterator.CHUNK_SIZE;
- G_Debug(this, "curr number nodes: " + this.numNodes_);
- }
- PROT_SafeDOMIterator.prototype.finishIfComplete = function() {
- if (this.shouldAbort() || this.numNodes_ >= this.maxNodes_) {
- G_Debug(this, "done. aborting: " + this.shouldAbort());
- this.fire("results", { callback: BindToObject(this.getResults, this) });
- return true;
- }
- G_Debug("not done yet");
- return false;
- }
- PROT_SafeDOMIterator.prototype.isReady = function() {
- return this.status_ == PROT_SafeDOMIterator.states.READY &&
- this.sandboxMgr_.hasData();
- }
- PROT_SafeDOMIterator.prototype.abort = function() {
- if (this.status_ == PROT_SafeDOMIterator.states.WORKING) {
- G_Debug(this, "aborting");
- this.status_ = PROT_SafeDOMIterator.states.ABORT;
- this.alarm_.cancel();
- this.alarm_ = null;
- } else {
- }
- }
- PROT_SafeDOMIterator.prototype.shouldAbort = function() {
- return this.status_ == PROT_SafeDOMIterator.states.ABORT;
- }
- PROT_SafeDOMIterator.prototype.maybeSetAbort = function(should_abort) {
- if (should_abort && !this.isReady()) {
- this.status_ = PROT_SafeDOMIterator.states.ABORT;
- }
- }
- PROT_SafeDOMIterator.prototype.getResults = function(results) {
- this.status_ = PROT_SafeDOMIterator.states.READY;
- if (typeof results != "string") {
- G_Debug(this, "sandbox returned wrong type for results: " + typeof
- results);
- } else {
- this.contentAnalyzer_.docIsComplete(this.doc_, results);
- }
- }
- var TEST_PROT_ContentAnalyzer = function(doc, listWarden) {
- var z = "contentanalyzer UNITTEST";
- G_debugService.enableZone(z);
- G_Debug(z, "Starting");
- contentAnalyzer = new PROT_ContentAnalyzer(listWarden,
- new TH_ThreadQueue(),
- true /* testing */);
- createDocFromString = function(doc, s, opt_id) {
- var iframe = doc.createElement("iframe");
- doc.documentElement.appendChild(iframe);
- iframe.setAttribute('id', opt_id);
- iframe.style.maxHeight = '0px';
- iframe.style.minHeight = '0px !important';
- var innerdoc = iframe.contentDocument;
- innerdoc.write(s);
- function docNClosure(doc, closure) {
- this.doc = doc;
- this.closure = closure;
- }
- function close() {
- doc.documentElement.removeChild(iframe);
- }
- return new docNClosure(innerdoc, close);
- }
- var iframeHtml = "<h1>Ebay affiliate</h1>";
- iframeHtml += "<img src=http://pics.ebaystatic.com/aw/pics/logos/logoEbay_150x70.gif>";
- iframeHtml += "<a href=http://ourpaypal.com>paypal.com</a>";
- iframeHtml += "<a href=http://paypal.com/privacy.html>Privacy policy</a>";
- iframeHtml += "<a href=http://somewhere.com>Not a juicy link</a>";
- iframeHtml += "<img src=http://somewhere_else.com>";
- iframeHtml += "<b><form action=\"/bad\" method=\"post\"><input type=\"text\" name=\"cc\">your credit card here</form>";
- var docNClosure = createDocFromString(doc,
- iframeHtml,
- 'unittestiframe');
- new G_Alarm(BindToObject(contentAnalyzer.maybeAnalyzeDoc,
- contentAnalyzer,
- docNClosure.doc),
- 5000);
- new G_Alarm(docNClosure.closure, 10*1000);
- new G_Alarm(function() { G_Debug(z, "Passed"); }, 15*1000);
- }
-